#include <pthread.h>
#include <stdio.h>
#include <semaphore.h>
#include <time.h>

typedef unsigned long long uint64_t; 

pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
pthread_barrier_t br;
sem_t sem;

void tern_init(int argc, char *argv[]);
//void tern_symbolic(void *addr, unsigned nbytes, const char *name);
void tern_before_landmark(unsigned landmark_type, unsigned hook_id, uint64_t arg1, uint64_t arg2, uint64_t arg3);
void tern_after_landmark(pthread_t *tid, unsigned landmark_type, unsigned hook_id, uint64_t ret_val, uint64_t arg1, uint64_t arg2, uint64_t arg3);

typedef void *(*thread_func_t)(void*);

int template(int argc, char *argv[])
{
        tern_init(argc, argv);
        tern_before_landmark(0, 0, 0, 0, 0);
        tern_after_landmark(NULL, 0, 0, 0, 0, 0, 0);

        fprintf(stderr, "pthread_self is %d\n", (int)pthread_self());

        pthread_mutex_init(&m, NULL);
        pthread_mutex_lock(&m);
        pthread_mutex_trylock(&m);
        pthread_mutex_unlock(&m);
        pthread_mutex_destroy(&m);

        pthread_cond_init(&cv, NULL);
        pthread_cond_signal(&cv);
        pthread_cond_broadcast(&cv);
        pthread_cond_wait(&cv, &m);
        pthread_cond_timedwait(&cv, &m, (struct timespec*)1);
        pthread_cond_destroy(&cv);

        pthread_barrier_init(&br, NULL, 1);
        pthread_barrier_wait(&br);
        pthread_barrier_destroy(&br);

        sem_post(&sem);
        sem_wait(&sem);
        sem_trywait(&sem);
        sem_timedwait(&sem, (struct timespec*)1);
        
        pthread_create((pthread_t*)1, NULL, (thread_func_t)1, NULL);
        pthread_join(0, NULL);
        pthread_exit(NULL);   /* must put this last, because gcc will skip deadcode. */
        return 0;
}

